package com.glsc.ngateway.opmanage.utils.report;

import cn.hutool.core.annotation.Alias;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.glsc.ngateway.common.api.platform.dto.it.networkassets.*;
import com.glsc.ngateway.common.api.platform.dto.other.TradeSeatFeesExportDto;
import com.glsc.ngateway.common.api.platform.dto.other.TradeSeatFeesShImportDto;
import com.glsc.ngateway.common.api.platform.dto.other.TradeSeatFlowSpeedImportDto;
import com.glsc.ngateway.opmanage.dto.*;
import com.glsc.ngateway.opmanage.utils.StringUtils;
import io.jsonwebtoken.lang.Collections;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 报表导出配置枚举
 *
 * @author xuchang
 */
@Getter
@AllArgsConstructor
public enum ReportFileConfigEnum {
    /**
     * 主机信息
     */
    HOST_INFORMATION_MAINTENANCE(0, 0, "主机信息.xlsx", getTitle(HostInformationMaintenanceDto.class),
            (ExportBuilder<List<HostInformationMaintenanceDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getId()),
                            StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getHostname()), StringUtils.getOrEmpty(h.getServiceZone()),
                            StringUtils.getOrEmpty(h.getDeviceRole()), StringUtils.getOrEmpty(h.getSnmpVersion()), StringUtils.getOrEmpty(h.getSnmpRoCommunity()),
                            StringUtils.getOrEmpty(h.getMgmtInterface()), StringUtils.getOrEmpty(h.getUsername()), StringUtils.getOrEmpty(h.getPassword()),
                            StringUtils.getOrEmpty(h.getTaskList()), StringUtils.getOrEmpty(h.getHostid()), StringUtils.getOrEmpty(h.getBindSerialNumList()),
                            StringUtils.getOrEmpty(h.getDeployedModeList())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, HostInformationMaintenanceDto.class)
    ),
    /**
     * 接口状态
     */
    INTERFACE_STATUS(0, 0, "接口状态.xlsx", getTitle(InterfaceStatusDto.class),
            (ExportBuilder<List<InterfaceStatusDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getId()),
                            StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getIfIndex()), StringUtils.getOrEmpty(h.getIfName()),
                            StringUtils.getOrEmpty(h.getIfType()), StringUtils.getOrEmpty(h.getIfHighSpeed()), StringUtils.getOrEmpty(h.getIfOperStatus()),
                            StringUtils.getOrEmpty(h.getIfErrDis())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, InterfaceStatusDto.class)
    ),
    /**
     * 维保信息
     */
    MAINTENANCE_INFORMATION(0, 0, "维保信息.xlsx", getTitle(MaintenanceInformationDto.class),
            (ExportBuilder<List<MaintenanceInformationDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getId()),
                            StringUtils.getOrEmpty(h.getSerialNum()), StringUtils.getOrEmpty(h.getMaintenanceInfo()), StringUtils.getOrEmpty(h.getSupplier()),
                            StringUtils.getOrEmpty(h.getStart()), StringUtils.getOrEmpty(h.getEnd()), StringUtils.getOrEmpty(h.getBindOa())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, MaintenanceInformationDto.class)
    ),
    /**
     * 网络资产
     */
    NETWORK_ASSET_MAINTENANCE(0, 0, "网络资产.xlsx", getTitle(NetworkAssetMaintenanceDto.class),
            (ExportBuilder<List<NetworkAssetMaintenanceDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getId()),
                            StringUtils.getOrEmpty(h.getSerialNum()), StringUtils.getOrEmpty(h.getVendor()), StringUtils.getOrEmpty(h.getModel()),
                            StringUtils.getOrEmpty(h.getOs()), StringUtils.getOrEmpty(h.getVersion()), StringUtils.getOrEmpty(h.getStatus()),
                            StringUtils.getOrEmpty(h.getSite()), StringUtils.getOrEmpty(h.getRack()), StringUtils.getOrEmpty(h.getUnit()),
                            StringUtils.getOrEmpty(h.getManufactureDate()), StringUtils.getOrEmpty(h.getExpiredDate()), StringUtils.getOrEmpty(h.getAssetNUM()),
                            StringUtils.getOrEmpty(h.getContractNUM())))
                    .collect(Collectors.toList()),
            //导入编辑，维保信息暂不处理
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, NetworkAssetMaintenanceDto.class)
    ),
    /**
     * 速率异常
     */
    RATE_EXP_EXL(0, 0, "速率异常.xlsx", getTitle(RateExceptionExcludeDto.class),
            (ExportBuilder<List<RateExceptionExcludeDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getId()),
                            StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getIfName()), StringUtils.getOrEmpty(h.getReferenceSpeed()),
                            StringUtils.getOrEmpty(h.getDescription())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, RateExceptionExcludeDto.class)
    ),
    /**
     * 交易单元费用预估流速
     */
    TRADE_SEAT_FLOW_SPEED_IMPORT(0, 0, "交易单元流速.xlsx", getTitle(TradeSeatFlowSpeedImportDto.class),
            (ExportBuilder<List<TradeSeatFlowSpeedImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getTradeSeatCode()),
                            StringUtils.getOrEmpty(h.getFlowSpeedWeight().toString())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, TradeSeatFlowSpeedImportDto.class)
    ),
    /**
     * 交易单元费用 上海
     */
    TRADE_SEAT_FEES_SH_IMPORT(0, 0, "交易单元上海申报.xlsx", getTitle(TradeSeatFeesShImportDto.class),
            (ExportBuilder<List<TradeSeatFeesShImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getTradeSeatCode()), StringUtils.getOrEmpty(h.getDataDate()),
                            StringUtils.getOrEmpty(h.getTradingOfferAmount()), StringUtils.getOrEmpty(h.getNoneTradingOfferAmount())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, TradeSeatFeesShImportDto.class)
    ),
    /**
     * 交易单元费用预估导出
     */
    TRADE_SEAT_FEES_EXPORT(0, 0, "交易单元费用预估导出文件.xlsx", getTitle(TradeSeatFeesExportDto.class),
            (ExportBuilder<List<TradeSeatFeesExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getTradeSeatMarket()), StringUtils.getOrEmpty(h.getDataDate().toString()), StringUtils.getOrEmpty(h.getTradeSeatCode()), StringUtils.getOrEmpty(h.getAnnualFees().toString()),
                            StringUtils.getOrEmpty(h.getUseFees().toString()), StringUtils.getOrEmpty(h.getFlowFees().toString()), StringUtils.getOrEmpty(h.getFlowSpeedFees().toString()), StringUtils.getOrEmpty(h.getTradeSeatName()),
                            StringUtils.getOrEmpty(h.getTradingOfferYearAmount()), StringUtils.getOrEmpty(h.getNoneTradingOfferYearAmount()), StringUtils.getOrEmpty(h.getTradingOfferAmount()),
                            StringUtils.getOrEmpty(h.getNoneTradingOfferAmount()), StringUtils.getOrEmpty(h.getFlowSpeedWeight())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, TradeSeatFeesExportDto.class)
    ),
    /**
     * 交易单元费用预估导出-资管子
     */
    TRADE_SEAT_FEES_EXPORT_AM(0, 0, "资管子交易单元费用预估.xlsx", getTitle(TradeSeatFeesEmailDto.class),
            (ExportBuilder<List<TradeSeatFeesEmailDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getTradeSeatCode()), StringUtils.getOrEmpty(h.getTradeSeatName().toString()),
                            StringUtils.getOrEmpty(h.getTradingOfferYearAmount().toString()), StringUtils.getOrEmpty(h.getNoneTradingOfferYearAmount().toString()),
                            StringUtils.getOrEmpty(h.getAnnualFees().toString()), StringUtils.getOrEmpty(h.getUseFees().toString()), StringUtils.getOrEmpty(h.getFlowFees().toString()),
                            StringUtils.getOrEmpty(h.getFlowSpeedFees().toString()), StringUtils.getOrEmpty(DateUtil.format(h.getChargeBeginDate(), "yyyy-MM")),
                            StringUtils.getOrEmpty(DateUtil.format(h.getChargeEndDate(), "yyyy-MM"))
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, TradeSeatFeesEmailDto.class)
    ),
    /**
     * 交易单元费用预估月度数据导出-资管子
     */
    TRADE_SEAT_FEES_EXPORT_AM_MONTH(0, 0, "资管子交易单元费用预估.xlsx", getTitle(TradeSeatFeesEmailMonthDto.class),
            (ExportBuilder<List<TradeSeatFeesEmailMonthDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getTradeSeatCode()), StringUtils.getOrEmpty(h.getTradeSeatName().toString()),
                            StringUtils.getOrEmpty(h.getTradingOfferYearAmount().toString()), StringUtils.getOrEmpty(h.getNoneTradingOfferYearAmount().toString()),
                            StringUtils.getOrEmpty(h.getAnnualFees().toString()), StringUtils.getOrEmpty(h.getUseFees().toString()), StringUtils.getOrEmpty(h.getFlowFees().toString()),
                            StringUtils.getOrEmpty(h.getFlowSpeedFees().toString()), StringUtils.getOrEmpty(DateUtil.format(h.getChargeBeginDate(), "yyyy-MM")),
                            StringUtils.getOrEmpty(DateUtil.format(h.getChargeEndDate(), "yyyy-MM"))
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, TradeSeatFeesEmailMonthDto.class)
    ),
    /**
     * 数字证书分摊结果导入
     */
    DIGITAL_KEY_FEES_EXPORT(0, 0, "数字证书分摊结果导入.xlsx", getTitle(DigitalKeyFeesImportDto.class),
            (ExportBuilder<List<DigitalKeyFeesImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getBrnOrgNo()), StringUtils.getOrEmpty(h.getFinCode()), StringUtils.getOrEmpty(h.getBrnOrgNm()),
                            StringUtils.getOrEmpty(h.getAnnualFee()), StringUtils.getOrEmpty(h.getAnnualAddedTax()), StringUtils.getOrEmpty(h.getPreviousAddedTax()),
                            StringUtils.getOrEmpty(h.getAssessedAmount()), StringUtils.getOrEmpty(h.getFinalAllocationResult())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DigitalKeyFeesImportDto.class)
    ),
    /**
     * 数字证书分摊明细导出
     */
    DIGITAL_KEY_FEES_DETAIL_EXPORT(0, 0, "数字证书分摊明细导入.xlsx", getTitle(DigitalKeyFeesItemImportDto.class),
            (ExportBuilder<List<DigitalKeyFeesItemImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getUnit()), StringUtils.getOrEmpty(h.getRate()), StringUtils.getOrEmpty(h.getBroFare()),
                            StringUtils.getOrEmpty(h.getBrnOrgNo()), StringUtils.getOrEmpty(h.getBrnOrgNm()), StringUtils.getOrEmpty(h.getCompOrgNo()),
                            StringUtils.getOrEmpty(h.getCompOrgNm())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DigitalKeyFeesItemImportDto.class)
    ),

    OUT_SYSTEM_EXPORT(0, 0, "外部系统权限.xlsx", getTitle(OutSystemExcelDto.class),
            (ExportBuilder<List<OutSystemExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(StringUtils.getOrEmpty(h.getSystemName()),
                            StringUtils.getOrEmpty(h.getAuthName1()), StringUtils.getOrEmpty(h.getAuthName2()), StringUtils.getOrEmpty(h.getAuthName3()),
                            StringUtils.getOrEmpty(h.getAuthName4()), StringUtils.getOrEmpty(h.getAuthName5()),
                            StringUtils.getOrEmpty(h.getDeptName()), StringUtils.getOrEmpty(h.getPostName()), StringUtils.getOrEmpty(h.getOperatorName()),
                            StringUtils.getOrEmpty(h.getUserName()), StringUtils.getOrEmpty(h.getUserAccount())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, OutSystemExcelDto.class)
    ),
    ARCHIVE_CLIENT_EXPORT(0, 0, "档案系统客户信息.xlsx", getTitle(ArchiveExcelDto.class),
            (ExportBuilder<List<ArchiveExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getClientName()), StringUtils.getOrEmpty(h.getClientId()), StringUtils.getOrEmpty(h.getWaitDealFileCount()),
                            StringUtils.getOrEmpty(h.getPartyName()), StringUtils.getOrEmpty(h.getPartyOrganCode()),
                            StringUtils.getOrEmpty(h.getClientType()), StringUtils.getOrEmpty(h.getBusinessLicenseCode()), StringUtils.getOrEmpty(h.getContactPersonName()),
                            StringUtils.getOrEmpty(h.getTelephone()), StringUtils.getOrEmpty(h.getMobile()), StringUtils.getOrEmpty(h.getMemo())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, ArchiveExcelDto.class)
    ),
    ORG_CLIENT_EXPORT(0, 0, "客户信息汇总表.xlsx", getTitle(OrgClientExcelDto.class),
            (ExportBuilder<List<OrgClientExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getPartyName()), StringUtils.getOrEmpty(h.getPartyOrganCode()), StringUtils.getOrEmpty(h.getClientId()),
                            StringUtils.getOrEmpty(h.getClientName()), StringUtils.getOrEmpty(h.getCnt())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, OrgClientExcelDto.class)
    ),
    COUNTER_PARTY_EXPORT(0, 0, "交易对手方信息.xlsx", getTitle(CounterPartyExcelDto.class),
            (ExportBuilder<List<CounterPartyExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getPartyName()), StringUtils.getOrEmpty(h.getPartyOrganCode()), StringUtils.getOrEmpty(h.getMemo()),
                            StringUtils.getOrEmpty(h.getEnableFlag())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CounterPartyExcelDto.class)
    ),
    NO_TRADE_CLIENT_EXPORT(0, 0, "暂未交易的客户清单.xlsx", getTitle(NoTraderClientExcelDto.class),
            (ExportBuilder<List<NoTraderClientExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getClientId()), StringUtils.getOrEmpty(h.getClientName())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, NoTraderClientExcelDto.class)
    ),
    KYC_SAC_LEDGER_FILE_EXPORT(0, 0, "本周收到的KYC、SAC文档清单请.xlsx", getTitle(BusinessLedgerFileExcelDto.class),
            (ExportBuilder<List<BusinessLedgerFileExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getFileName()), StringUtils.getOrEmpty(h.getMemo())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, BusinessLedgerFileExcelDto.class)
    ),
    LEDGER_FILE_EXPORT(0, 0, "台账kyc&sac文件清单导出.xlsx", getTitle(LedgerFileExportDto.class),
            (ExportBuilder<List<LedgerFileExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getCustomerNo()), StringUtils.getOrEmpty(h.getFileName()),
                            StringUtils.getOrEmpty(h.getType()), StringUtils.getOrEmpty(h.getWorkValue()),
                            StringUtils.getOrEmpty(DateUtil.format(h.getCreateTime(), "yyyy-MM-dd HH:mm:ss")), StringUtils.getOrEmpty(h.getRemark())
                            , "Y".equals(h.getFileActualReceive()) ? "已签收" : "未签收"))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, LedgerFileExportDto.class)
    ),
    DEPOSITORY_DAY_PROFIT(0, 0, "保证金管理-每日收益导出数据.xlsx", getTitle(DepositoryDayProfitExcelDto.class),
            (ExportBuilder<List<DepositoryDayProfitExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getBankName()), StringUtils.getOrEmpty(h.getInterestRate().toString()), StringUtils.getOrEmpty(h.getBankBalance().toString()),
                            StringUtils.getOrEmpty(h.getInterest().toString()), StringUtils.getOrEmpty(h.getQuarterInterest().toString()), StringUtils.getOrEmpty(h.getCounterBalance().toString()),
                            StringUtils.getOrEmpty(h.getStowageRatio().toString()), StringUtils.getOrEmpty(h.getCustomerInterest().toString()), StringUtils.getOrEmpty(h.getSpreadIncome().toString())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DepositoryDayProfitExcelDto.class)
    ),
    DEPOSITORY_DAY_TRIAL(0, 0, "保证金管理-每日收益导出数据.xlsx", getTitle(DepositoryDayTrialExcelDto.class),
            (ExportBuilder<List<DepositoryDayTrialExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getBankName()), StringUtils.getOrEmpty(h.getCounterBalance().toString()), StringUtils.getOrEmpty(h.getBankBalance().toString()),
                            StringUtils.getOrEmpty(h.getInterestRate().toString()), StringUtils.getOrEmpty(h.getInterest().toString()), StringUtils.getOrEmpty(h.getDepositFloor().toString()),
                            StringUtils.getOrEmpty(h.getAdjustTrial().toString()), StringUtils.getOrEmpty(h.getHandAdjust().toString()), StringUtils.getOrEmpty(h.getTrialInterestChange().toString()),
                            StringUtils.getOrEmpty(h.getPurchaseDay().toString()), StringUtils.getOrEmpty(h.getWithdrawalDay().toString())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DepositoryDayTrialExcelDto.class)
    ),
    DEPOSITORY_BASE_DATE_QUARTER(0, 0, "保证金管理-季度基础数据.xlsx", getTitle(DepositoryBaseDataExcelDto.class),
            (ExportBuilder<List<DepositoryBaseDataExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getBankName()), StringUtils.getOrEmpty(h.getEffectBeginDate()), StringUtils.getOrEmpty(h.getEffectEndDate()), StringUtils.getOrEmpty(h.getAverageMargin().toString()),
                            StringUtils.getOrEmpty(h.getAverageBankBalance().toString()), StringUtils.getOrEmpty(h.getAverageStowageRatio().toString()), StringUtils.getOrEmpty(h.getAverageStowageRatio().toString()),
                            StringUtils.getOrEmpty(h.getInterestRate().toString()), StringUtils.getOrEmpty(h.getIncrease10pMargin().toString()), StringUtils.getOrEmpty(h.getOneDayCost().toString()),
                            StringUtils.getOrEmpty(h.getEstimatedMinDeposits().toString()), StringUtils.getOrEmpty(h.getEstimatedMaxDeposits().toString()), StringUtils.getOrEmpty(h.getSafeValue().toString()),
                            StringUtils.getOrEmpty(h.getIntendedDeposit().toString()), StringUtils.getOrEmpty(h.getIntendedDepositHand().toString()), StringUtils.getOrEmpty(h.getSafeValueInf().toString()),
                            StringUtils.getOrEmpty(h.getIntendedDepositHandInf().toString())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DepositoryBaseDataExcelDto.class)
    ),
    DEPOSITORY_COUNTER_BANK_QUARTER(0, 0, "保证金管理-季度柜台银行数据.xlsx", getTitle(DepositoryCounterBankExcelDto.class),
            (ExportBuilder<List<DepositoryCounterBankExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getEffectBeginDate()), StringUtils.getOrEmpty(h.getEffectEndDate()), StringUtils.getOrEmpty(h.getCounterBalanceAverage().toString()),
                            StringUtils.getOrEmpty(h.getCustomerInterestAmount().toString()), StringUtils.getOrEmpty(h.getCustomerInterestRate().toString()),
                            StringUtils.getOrEmpty(h.getAverageBankBalance().toString()), StringUtils.getOrEmpty(h.getBankInterestAmount().toString()), StringUtils.getOrEmpty(h.getAverageBankRate().toString())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DepositoryCounterBankExcelDto.class)
    ),
    DEPOSITORY_DAY_START_DATA(0, 0, "保证金日出数据.xlsx", getTitle(DepositoryStartDataExcelDto.class),
            (ExportBuilder<List<DepositoryStartDataExcelDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getBankName()), StringUtils.getOrEmpty(h.getMarginTotalAmt()), StringUtils.getOrEmpty(h.getBankSecTranBalance().toString()),
                            StringUtils.getOrEmpty(h.getMarginGtAmt().toString())
                    ))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(1, 2, DepositoryStartDataExcelDto.class)
    ),

    ;

    /**
     * 开始行
     */
    private final int beginRow;
    /**
     * 开始列
     */
    private final int beginCol;
    /**
     * 导出文件名
     */
    private final String fileName;
    /**
     * 表头
     */
    private final List<String> title;
    /**
     * 导出数据build方法
     */
    private final ExportBuilder exportBuilder;
    /**
     * 导入数据build方法
     */
    private final ReadImportBuilder readImportBuilder;

    /**
     * 通过反射获取类及父类中带有@Alias字段的value
     */
    private static List<String> getTitle(Class<?> clz) {
        List<Class<?>> clzList = new ArrayList<>();
        while (clz != null) {
            clzList.add(clz);
            clz = clz.getSuperclass();
        }
        List<String> title = new ArrayList<>();
        //倒序先将父节点的字段加入
        for (int i = clzList.size() - 1; i >= 0; i--) {
            clz = clzList.get(i);
            List<String> fields = Arrays.stream(clz.getDeclaredFields()).filter(f -> f.isAnnotationPresent(Alias.class)).map(f -> f.getAnnotation(Alias.class).value()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(fields)) {
                title.addAll(fields);
            }
        }
        return title;
    }

    /**
     * 构建导出数据
     */
    public <T> List<List<String>> export(T data) {
        return this.getExportBuilder().build(data);
    }

    /**
     * 读取导入数据
     */
    public <T> List<T> readImport(MultipartFile file) throws IOException {
        return this.getReadImportBuilder().read(file);
    }

    @FunctionalInterface
    private interface ExportBuilder<T> {
        List<List<String>> build(T data);
    }

    @FunctionalInterface
    private interface ReadImportBuilder<T> {
        List<T> read(MultipartFile file) throws IOException;
    }
}
